package com.smsc.headend.task.engine.handler.impl.firmware;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Preconditions;
import com.smsc.headend.common.constant.DeviceModel;
import com.smsc.headend.common.enums.errorcode.TaskHandlerErrorCode;
import com.smsc.headend.module.asset.dmo.ComConfigDMO;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.AtomicTaskState;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import com.smsc.headend.task.engine.service.DeviceFirmwareVersionService;
import com.smsc.headend.task.engine.service.FeignAssetManagementService;
import com.smsc.headend.task.engine.service.firmware.FirmwareService;
import com.smsc.headend.task.engine.service.task.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @author qinbin
 * @date 2021/04/28
 */
@Slf4j
@Service
public class GetFirmwareVersionHandler implements TaskHandler {
    @Autowired
    TaskDAO taskDAO;

    @Autowired
    CosemXmlService cosemXmlService;

    @Autowired
    TaskService taskService;

    @Autowired
    DeviceFirmwareVersionService deviceFirmwareVersionService;

    @Value("#{T(java.lang.Integer).parseInt('${fwu.step.retryTimes:2}')}")
    Integer firmwareStepsRetry;

    @Autowired
    FirmwareService firmwareService;

    @Autowired
    FeignAssetManagementService assetManagementService;

    private final static String OCTET_STRING = "OctetString";


    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException(TaskHandlerErrorCode.DEVICE_DATA_TYPE_NOT_SUPPORT.toString());
        }
        log.debug("GetFirmwareVersionHandler, task_no {}", task.getTaskNo());
        CosemData cosemData = (CosemData) deviceData;
        log.debug("GetFirmwareVersionHandler, deviceData {}", JSONUtil.toJsonStr(cosemData));
        Object data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
        String firmwareVersion;
        if (OCTET_STRING.equalsIgnoreCase(cosemData.getType())) {
            try {
                firmwareVersion = HexUtil.decodeHexStr(Convert.toStr(data)).trim();
            } catch (Exception e) {
                firmwareVersion = Convert.toStr(data);
            }
        } else {
            firmwareVersion = Convert.toStr(data);
        }


        String rawVersion = firmwareVersion;
        log.debug("read device firmware version success, value {}", rawVersion);
        Long fwTypeId = Convert.toLong(this.getParameterMap(task, atomicTask).get("fwTypeId"));
        ComConfigDMO configDMO = null;
//        if (task.getMeterId() == null) {
//            configDMO = assetService.getComConfigById(task.getComId());
//            Preconditions.checkNotNull(configDMO);
//            //Wisun DCU MasterModule 固件id 11，12 代表同一版本信息中包含两个固件的版本号 ， COM-MASTER是倒数两位， COM-MASTER1 倒数3，4位
//            if (DeviceModel.WFCT_960 == configDMO.getModelId() && (fwTypeId == 11L || fwTypeId == 12L)) {
//                String first11Version = StrUtil.sub(firmwareVersion, firmwareVersion.length() - 2, firmwareVersion.length());
//                String sec12Version = StrUtil.sub(firmwareVersion, firmwareVersion.length() - 4, firmwareVersion.length() - 2);
//                firmwareVersion = fwTypeId == 11L ? first11Version : sec12Version;
//            }
//        }
        taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(fwTypeId), firmwareVersion, Long.valueOf(1 * 60 * 60), true);
        if (StringUtils.isNotEmpty(firmwareVersion)) {
            firmwareService.saveFirmwareVersion(rawVersion, fwTypeId, task, null, configDMO);
        }
        return 1;
    }


    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, taskType:{},meterId:{}", message, task.getTaskType(), task.getMeterId());
        if (atomicTask.getGroupId() == OperationGroup.GetFirmwareVersion.getId().intValue()) {
            Long fwTypeId = Convert.toLong(this.getParameterMap(task, atomicTask).get("fwTypeId"));
            if (task.getIsODR()) {
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(fwTypeId), String.format("[%s]", message), 3600L, false);
            }
        }
        if (firmwareService.isRetryMessageType(message)) {
            AtomicTaskState atomicTaskState = taskDAO.hashGetAtomicTaskState(atomicTask.getAtomicTaskNo());
            if (atomicTaskState.getRetryTimes() >= firmwareStepsRetry) {
                log.error("Image transfer failed retry times over");
                return -1;
            }
            log.error("Image transfer failed retry times {}", atomicTaskState.getRetryTimes());
            atomicTaskState.setStored(false);
            taskDAO.hashSetAtomicTaskState(atomicTask.getAtomicTaskNo(), task, atomicTaskState.getRetryTimes() + 1, atomicTaskState);
            return 0;
        }
        return -1;
    }

}
